home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / wp2x110.zip / DOPEN.C < prev    next >
C/C++ Source or Header  |  1991-08-20  |  4KB  |  156 lines

  1. /*$Id: dopen.c 1.2 91/08/20 15:18:51 raymond Exp $*/
  2.  
  3. /* dopen() is a massively system-dependent function, so I've placed
  4.  * it in a separate file.
  5.  */
  6.  
  7. /* Macros used...
  8.  *
  9.  *  IS_ABS   -- a macro that returns nonzero if the string argument is an
  10.  *              absolute path, or 0 if it is a relative path.
  11.  *  PATH_STR -- a string of characters which separate directory components.
  12.  *  SUF_STR  -- suffix for configuration files
  13.  *  PATH_SEP -- character to separate directory from filename.
  14.  *  LIST_SEP -- character that separates pathnames in a list.
  15.  *  exists(f) -- returns nonzero if the file f exists.
  16.  *        if not defined, then use fopen to determine existence.
  17.  *  HAS_ENV  -- if defined, environment variables are searched.
  18.  *
  19.  */
  20.  
  21. /*
  22.  *  Our algorithm is to try the following in sequence, until one works.
  23.  *
  24.  *  The filename as-is.
  25.  *  The filename with SUF_STR appended.
  26.  *
  27.  *  If IS_ABS returns nonzero, then fail.
  28.  *
  29.  *  Else, we call the system-dependent get_dir() function.  Each call
  30.  *  provides a directory to look in.
  31.  *
  32.  *  For each directory, append the filename (perhaps inserting the
  33.  *  PATH_SEP).  If that fails, try again after appending SUF_STR.
  34.  *
  35.  *  When we run out of directories, we fail.
  36.  */
  37.  
  38. #ifdef UNIX
  39. #define HAS_ENV
  40. #define exists(f) (access(f, 0) == 0)
  41. #define IS_ABS(f) (*f == '/')
  42. #define SUF_STR ".cfg"
  43. #define PATH_SEP '/'
  44. #define PATH_STR "/"
  45. #define LIST_SEP ':'
  46. #endif
  47.  
  48. #ifdef MSDOS
  49. #define HAS_ENV
  50. #include <io.h>
  51. #define exists(f) (access(f, 0) == 0)
  52. #define IS_ABS(f) (f[1] == ':' || strchr(PATH_STR, *f))
  53. #define SUF_STR ".cfg"
  54. #define PATH_SEP '/'
  55. #define PATH_STR "/\\:"
  56. #define LIST_SEP ';'
  57. #endif
  58.  
  59. #ifdef VMS                /* VMS is really different */
  60. #define IS_ABS(f) (strchr(f, ':') || strchr(PATH_STR, *f))
  61. #define SUF_STR ".cfg"
  62. #define PATH_SEP '.'
  63. #define PATH_STR "[.]"
  64. #endif
  65.  
  66. #ifdef AMIGA
  67. #define IS_ABS(f) (strchr(f, ':') || *f == '/')
  68. #define SUF_STR ".cfg"
  69. #define PATH_SEP '/'
  70. #define PATH_STR "/"
  71. #endif
  72.  
  73. /* If user specified no operating system, be very pessimistic.
  74.  * Don't do anything beyond adding the `.cfg. suffix.
  75.  */
  76. #ifndef SUF_STR
  77. #define IS_ABS 1
  78. #define SUF_STR ".cfg"
  79. #undef PATH_SEP
  80. #undef PATH_STR
  81. #undef HAS_ENV
  82. #endif
  83.  
  84. /* If we don't have an exists(), then we'll just use fopen. */
  85. #ifndef exists
  86. #define exists(f) (descriptor = fopen(f, "rt"))
  87. #endif
  88.  
  89. #ifdef HAS_ENV
  90. /* We search a handful of environment variables */
  91. const char *envlist[] = { "PATH", "DPATH", "WP2XDIR", NULL };
  92.  
  93. char *get_dir(void)
  94. {
  95.     static const char **nextenv = envlist;
  96.     static const char *nextpath = NULL;
  97.     char *s;
  98.  
  99.     /* get the next environment variable */
  100.     while (nextpath == NULL || *nextpath == '\0') {
  101.     if (*nextenv == NULL) return NULL;  /* out of ideas */
  102.         nextpath = getenv(*nextenv++);
  103.     }
  104.  
  105.     /* copy the next path component into the string pool */
  106.     /* We can ignore the UNIX convention that a null component
  107.      * denotes the current directory, since the current directory
  108.      * has already been searched before we get to this point.
  109.      */
  110.     s = pool;
  111.     while (*nextpath && *nextpath != LIST_SEP) *s++ = *nextpath++;
  112.     if (*nextpath) nextpath++;
  113.  
  114.     return s;                /* where to append the filename */
  115. }
  116. #else
  117. /* On non-UNIX systems, we don't have environment variables. */
  118. /* We might have other things, though, so insert your local version here */
  119. char *get_dir(void) { return NULL; }
  120. #endif
  121.  
  122. /* s is where to copy the filename, and f is the filename to try. */
  123.  
  124. int try_directory(char *s, const char *f)
  125. {
  126.     if (s > pool && !strchr(PATH_STR, s[-1])) *s++ = PATH_SEP;
  127.     strcpy(s, f);
  128.  
  129.     if (exists(pool) || (strcat(s, SUF_STR), exists(pool))) {
  130.     if (!descriptor) descriptor = efopen(pool, "rt");
  131.     return 1;
  132.     }
  133.  
  134.     return 0;
  135. }
  136.  
  137. void dopen(const char *f)
  138. {
  139.     char *s;
  140.  
  141.     /* First, try it as-is */
  142.     if (try_directory(pool, f)) return;
  143.  
  144. #ifdef WP2X_DIR
  145.     strcpy(pool, WP2X_DIR);
  146.     if (try_directory(strchr(pool, '\0'), f)) return;
  147. #endif
  148.  
  149.     /* Skip if an absolute path */
  150.     if (!IS_ABS(f)) {
  151.     /* Iterate through the possible directories */
  152.     while (s = get_dir()) if (try_directory(s, f)) return;
  153.     }
  154.     error(NULL, "Cannot find file %s\n", f);
  155. }
  156.